<?php
// +----------------------------------------------------------------------
// | B5Yii2CMF V3.0 [快捷通用基础管理开发平台]
// +----------------------------------------------------------------------
// | Author: 冰舞 <357145480@qq.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace api\utils\libs;

use common\extend\exception\ErrorCode;
use common\extend\exception\B5HttpException;
use common\models\system\AppToken;
use yii\base\ActionFilter;
use Yii;

/**
 * 判断token的过滤器
 * Class FilterLogin
 * @package api\modules\admin\utils
 */
class FilterLogin extends ActionFilter
{
    use TraitToken;

    /**
     * 平台类型
     * @var string
     */
    public string $plat = '';

    /**
     * 用户类型
     * @var string
     */
    public string $type = 'admin';

    /**
     * 接口登录参数
     * @var string
     */
    public string $key = 'authorization';

    /**
     * 是否允许未登录
     * true时未登录会直接返回未登录错误
     * false需自己根据__token进行判断
     * 主要用于某个控制器中登录或者未登录都可以进行的操作
     * @var bool
     */
    public bool $failBack = true;

    /**
     * 方法前执行操作
     * @param $action
     * @return bool
     * @throws B5HttpException
     */
    public function beforeAction($action): bool
    {
        if (!parent::beforeAction($action)) {
            return false;
        }
        $tokenRecord = $this->checkLoginToken();
        if ($tokenRecord) {
            //将token信息传递
            $bodyParams = Yii::$app->request->bodyParams;
            $bodyParams['__token__'] = $tokenRecord->toArray();
            Yii::$app->request->setBodyParams($bodyParams);
        }
        return true;
    }


    /**
     * 验证登录信息
     * @return AppToken|false
     * @throws B5HttpException
     */
    public function checkLoginToken() {
        $token = '';
        if ($this->key == 'authorization') {
            $authorization = Yii::$app->request->getHeaders()->get('authorization');
            if ($authorization) $token = trim(str_replace('Bearer', '', $authorization));
        } else {
            if (!$token) $token = Yii::$app->request->post($this->key, '');
            if (!$token) $token = Yii::$app->request->get($this->key, '');
        }

        if (!$token) {
            if ($this->failBack) {
                throw new B5HttpException(400, '请先登录', ErrorCode::API_TOKEN_ERROR);
            }
            return false;
        }

        if (!$this->plat) {
            if (Yii::$app->request->isPost){
                $plat = Yii::$app->request->post('_plat_', '');
            } else {
                $plat = Yii::$app->request->get('_plat_', '');
            }
            if ($plat && in_array($plat, ['h5', 'web', 'app'])) {
                $this->plat = $plat;
            } else if ($this->type == 'admin') {
                $this->plat = 'web';
            } else if ($this->type == 'user') {
                $this->plat = 'web';
            }
        }
        $tokenRecord = $this->getToken($token, $this->type, $this->plat);
        if (!$tokenRecord) {
            if ($this->failBack) {
                throw new B5HttpException(400, '登录会话失效，请重新登录', ErrorCode::API_TOKEN_ERROR);
            }
            return false;
        }
        return $tokenRecord;
    }
}